<?php
namespace app\common\model;

use app\common\model\UserDownloadTimes;
use app\common\model\UserSiteAccess;
use think\facade\Db;
use think\facade\Request;
use think\Model;
use think\model\concern\SoftDelete;

class UserMealOrder extends Model
{
    use SoftDelete;
    protected $pk                = 'order_id';
    protected $json              = ['vip_access', 'download_times', 'proxy_access', 'payinfo'];
    protected $jsonAssoc         = true;
    protected $deleteTime        = 'delete_time';
    protected $defaultSoftDelete = 0;
    protected $type              = [
        'create_time' => 'timestamp',
        'update_time' => 'timestamp',
        'out_time'    => 'timestamp',
        'pay_time'    => 'timestamp',
    ];

    public static function onBeforeInsert($data)
    {
        $data->order_id    = date('YmdHis') . random(16, 1);
        $data->create_time = Request::time();
        $data->create_ip   = Request::ip();
        $data->out_time    = Request::time() + 86400;
        $data->status      = 0;
    }

    public function getTypeTextAttr($value, $data)
    {
        switch ($data['type']) {
            case 'vip':
                return 'VIP升级';
                break;
            case 'download':
                return '下载次数';
                break;

            default:
                return '未知';
                break;
        }
    }

    public function getStatusTextAttr($value, $data)
    {
        switch ($data['status']) {
            case -1:
                return '失效';
                break;
            case 0:
                return '待支付';
                break;
            case 1:
                return '已完成';
                break;

            default:
                return '未知';
                break;
        }
    }

    public function getTextColorAttr($value, $data)
    {
        switch ($data['status']) {
            case -1:
                return 'text-danger';
                break;
            case 0:
                return 'text-info';
                break;
            case 1:
                return 'text-success';
                break;

            default:
                return 'text-secondary';
                break;
        }
    }

    public function getAllPriceAttr($value, $data)
    {
        return $data['price'] * $data['buy_number'];
    }

    public function getPayTypeAttr($value, $data)
    {
        if (empty($data['payinfo'])) {
            return '未支付';
        }
        if (!empty($data['payinfo']['pay_type']) && $data['payinfo']['pay_type'] == 'balance') {
            return '余额支付';
        }
        if (!empty($data['payinfo']['openid'])) {
            return '微信支付';
        }
        if (!empty($data['payinfo']['alipay_trade_query_response'])) {
            return '支付宝';
        }
        if (!empty($data['payinfo']['retmsg'])) {
            return 'QQ钱包';
        }
        return '未知方式';
    }

    public function goPay($payment)
    {
        global $_G;
        $data = [
            'trade_type' => 'NATIVE',
            'order_id'   => $this->getAttr('order_id'),
            'price'      => round($this->getAttr('price') * $this->getAttr('buy_number'), 2),
            'subject'    => $this->getAttr('title'),
            'body'       => $this->getAttr('body'),
        ];
        if ($payment == 'alipay') {
            if (!$_G['setting']['alipay_switch']) {
                return ['code' => 0, 'msg' => '暂未开放支付宝在线充值'];
            }
            return (new \payment\Alipay)
                ->setConfig([
                    'notify_url' => url('index/notify/alipay', [], false, true),
                ])
                ->setOrder($data)
                ->unifiedOrder();
        } else if ($payment == 'wxpay') {
            if (!$_G['setting']['wxpay_switch']) {
                return ['code' => 0, 'msg' => '暂未开放微信支付在线充值'];
            }
            $result = (new \payment\Wxpay)
                ->setConfig([
                    'notify_url' => url('index/notify/wxpay', [], false, true),
                ])
                ->setOrder($data)
                ->unifiedOrder();
            if (empty($result['code_url'])) {
                return ['code' => 0, 'msg' => '生成二维码失败，请重试'];
            }
            return ['code' => 1, 'msg' => '请使用微信扫码完成支付', 'qrcode' => $result['code_url']];
        } else if ($payment == 'qqpay') {
            if (!$_G['setting']['qqpay_switch']) {
                return ['code' => 0, 'msg' => '暂未开放QQ钱包在线充值'];
            }
            $result = (new \payment\Qqpay)
                ->setConfig([
                    'notify_url' => url('index/notify/qqpay', [], false, true),
                ])
                ->setOrder($data)
                ->unifiedOrder();
            if (empty($result['code_url'])) {
                return ['code' => 0, 'msg' => '生成二维码失败，请重试'];
            }
            return ['code' => 1, 'msg' => '请使用QQ扫码完成支付', 'qrcode' => $result['code_url']];
        } else if ($payment == 'balance') {
            if ($_G['user']['balance'] < $data['price']) {
                return ['code' => 0, 'msg' => '账户余额不足，请选择其他支付方式'];
            }
            $this->payinfo     = ['pay_type' => 'balance'];
            $this->status      = 1;
            $this->update_time = Request::time();
            $this->pay_time    = Request::time();
            $this->save();
            $this->pay_succeed();

            UserMain::where('uid', '=', $this->getAttr('uid'))->update(['balance' => Db::raw('balance-' . $data['price'])]);
            return ['code' => 1, 'msg' => '购买成功'];
        }
        return ['code' => 0, 'msg' => '请选择正确的支付通道'];
    }

    public function query()
    {
        global $_G;
        $payinfo = false;
        if ($_G['setting']['alipay_switch']) {
            $result = (new \payment\Alipay)->setOrder(['order_id' => $this->getAttr('order_id')])->queryOrder();
            if (!empty($result['transaction_id']) && $this->getAttr('status') !== 1) {
                $payinfo = $result;
            }
        }
        if ($_G['setting']['wxpay_switch'] && $payinfo === false) {
            $result = (new \payment\Wxpay)->setOrder(['order_id' => $this->getAttr('order_id')])->queryOrder();
            if (!empty($result['transaction_id']) && $this->getAttr('status') !== 1) {
                $payinfo = $result;
            }
        }
        if ($_G['setting']['qqpay_switch'] && $payinfo === false) {
            $result = (new \payment\Qqpay)->setOrder(['order_id' => $this->getAttr('order_id')])->queryOrder();
            if (!empty($result['transaction_id']) && $this->getAttr('status') !== 1) {
                $payinfo = $result;
            }
        }
        if ($payinfo !== false) {
            $this->status      = 1;
            $this->update_time = Request::time();
            $this->pay_time    = Request::time();
            $this->payinfo     = json_encode($payinfo);
            $this->save();
            $this->pay_succeed();
        }
        return $payinfo;
    }

    private function pay_succeed()
    {
        if ($this->getAttr('type') == 'vip') {
            $vip_access = $this->getAttr('vip_access') ?: [];
            foreach (UserSiteAccess::where('uid', '=', $this->getAttr('uid'))->select() as $access) {
                if (empty($vip_access[$access['site_id']])) {
                    continue;
                }
                $is_update = false;
                foreach (['day_times', 'week_times', 'month_times', 'year_times', 'max_times', 'out_time'] as $key) {
                    if ($access->$key == 0 || !isset($vip_access[$access['site_id']][$key])) {
                        continue;
                    }
                    if ($vip_access[$access['site_id']][$key] == 0) {
                        $access->$key = 0;
                    } else if ($vip_access[$access['site_id']][$key] > 0) {
                        if ($key == 'out_time') {
                            $access->$key = ($access->$key <= Request::time() ? Request::time() : $access->$key) + $vip_access[$access['site_id']][$key] * 3600;
                        } else {
                            $access->$key = $access->$key < 0 ? $vip_access[$access['site_id']][$key] : $vip_access[$access['site_id']][$key] + $access->$key;
                        }
                    }
                    $is_update = true;
                }
                if ($is_update === true) {
                    $access->save();
                }
                unset($vip_access[$access['site_id']]);
            }
            if (!empty($vip_access)) {
                foreach ($vip_access as $site_id => $access) {
                    if (empty($site_id)) {
                        continue;
                    }
                    $av_times = [];
                    foreach (['day_times', 'week_times', 'month_times', 'year_times', 'max_times'] as $time_key) {
                        if (isset($access[$time_key]) && $access[$time_key] > 0) {
                            $av_times[] = $access[$time_key];
                        }
                    }

                    $int_times = empty($av_times) ? -1 : max($av_times);

                    $day_times = $week_times = $month_times = $year_times = $max_times = 0;
                    foreach (['day_times', 'week_times', 'month_times', 'year_times', 'max_times'] as $time_key) {

                        if (isset($access[$time_key])) {
                            if ($access[$time_key] < 0) {
                                ${$time_key} = $int_times;
                            } else if ($access[$time_key] > 0) {
                                ${$time_key} = $access[$time_key];
                            }
                        }
                    }
                    $out_time = 0;
                    if (isset($access['out_time'])) {
                        if ($access['out_time'] < 0) {
                            if ($int_times < 0) {
                                $out_time = -1;
                            } else if ($int_times > 0) {
                                $out_time = 72;
                            } else {
                                $out_time = 0;
                            }
                        } else if ($access['out_time'] > 0) {
                            $out_time = $access['out_time'];
                        }
                    }
                    UserSiteAccess::create([
                        'uid'         => $this->getAttr('uid'),
                        'site_id'     => $site_id,
                        'day_times'   => $day_times,
                        'week_times'  => $week_times,
                        'month_times' => $month_times,
                        'year_times'  => $year_times,
                        'max_times'   => $max_times,
                        'out_time'    => $out_time,
                    ]);
                }
            }
        } else if ($this->getAttr('type') == 'download') {
            $data           = [];
            $download_times = $this->getAttr('download_times') ?: [];
            foreach ($download_times as $site_id => $value) {
                if ($value['times'] > 0 && $value['out_time'] >= 0) {
                    $data[] = [
                        'uid'      => $this->getAttr('uid'),
                        'site_id'  => $site_id,
                        'times'    => $value['times'] * $this->getAttr('buy_number'),
                        'from'     => 'buy',
                        'summary'  => '购买下载套餐',
                        'out_time' => $value['out_time'] == 0 ? 0 : (Request::time() + $value['out_time'] * 3600),
                        'status'   => 1,
                    ];
                }
            }
            if (!empty($data)) {
                (new UserDownloadTimes)->saveAll($data);
            }
        }
    }

    public function user()
    {
        return $this->belongsTo(UserMain::class, 'uid');
    }
}
